<template>
  <div :class="cn('cg-table', TableClass)" ref="rootElement">
    <div class="cg-table-content" ref="contentStyle">
      <div :class="cn('cg-table__header-wrapper', TableHeaderClass)" ref="head">
        <table-header :store="tableStore" />
      </div>
      <div :class="cn('cg-table__body-wrapper', TableBodyClass)" ref="body" :style="bodyStyle">
        <cg-scrollbar ref="scrollbar" tag="div" wrap-height="max" :style="scrollbarStyle" @handle-scroll="handleScroll">
          <table-body :store="tableStore">
            <slot></slot>
          </table-body>
        </cg-scrollbar>
      </div>
      <div v-if="showPagination" :class="cn('cg-table__pagination', TablePaginationClass)" ref="pagination">
        <pagination :current-page="page.currentPage || 0" :page-size="page.pageSize || 0" :total="page.totalNum || 0"
          @current-change="handleCurrentChange" />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, watch, computed, nextTick } from 'vue'
import { cn } from '../../lib/utils'
import { addResizeListener, removeResizeListener } from '../../tools/resize-event'
import TableHeader from './table-header'
import TableBody from './table-body'
import Pagination from '../cg-pagination/main.vue'
import { TableClass, TableHeaderClass, TableBodyClass, TablePaginationClass } from './tools'
import _ from 'lodash'

defineOptions({
  name: 'cg-table'
})

// 定义类型
interface Column {
  prop?: string
  label?: string
  width?: number
  type?: string
  items?: Array<{
    key: string
    text: string
    click: (row: any) => void
  }>
  render?: (value: any, row: any) => any
}

interface Page {
  currentPage: number
  pageSize: number
  totalNum: number
}

interface TableStore {
  columns: Column[]
  data: any[]
  width: number
  contentWidth: number
  colWidths: number[]
  bodyHeight: number
  scrollbarWidth: number
}

interface Props {
  columns: Column[]
  data: any[]
  page?: Partial<Page>
  showPagination?: boolean
}

// 定义props
const props = withDefaults(defineProps<Props>(), {
  page: () => ({ currentPage: 1, pageSize: 10, totalNum: 0 }),
  showPagination: true
})

// 定义emits
const emit = defineEmits<{
  'current-change': [page: number]
}>()

// 定义ref
const rootElement = ref<HTMLElement | null>(null)
const head = ref<HTMLElement | null>(null)
const body = ref<HTMLElement | null>(null)
const pagination = ref<InstanceType<typeof Pagination> | null>(null)
const scrollbar = ref<any>(null)

// 使用reactive创建响应式的tableStore
const tableStore = reactive<TableStore>({
  columns: [],
  data: [],
  width: 0,
  contentWidth: 0,
  colWidths: [],
  bodyHeight: 0,
  scrollbarWidth: 0
})

// 计算属性
const bodyStyle = computed(() => ({
  height: `${tableStore.bodyHeight}px`
}))

const scrollbarStyle = computed(() => ({
  width: `${tableStore.width}px`
}))

const contentStyle = computed(() => {
  if (!rootElement.value) return {}

  const { clientHeight } = rootElement.value

  if (head.value && pagination.value && props.showPagination) {
    const headHeight = head.value.clientHeight
    console.log("pagination", pagination)
    const paginationHeight = 0
    //  pagination.value.clientHeight
    const contentHeight = Math.min(clientHeight, headHeight + tableStore.bodyHeight + paginationHeight)
    return { height: `${contentHeight}px` }
  }

  return {}
})

// 更新表格宽度的方法
const updateTableWidth = (width: number) => {
  tableStore.width = Math.floor(width)
  console.log("tableStore.width", tableStore.width)

  let lastWidth = tableStore.width
  const colWidths: number[] = []
  const customColumn: number[] = []

  if (tableStore.columns.length) {
    tableStore.columns.forEach((column, index) => {
      if (typeof column.width === 'number') {
        colWidths[index] = column.width
        lastWidth -= column.width
      } else {
        customColumn.push(index)
      }
    })

    // 计算自适应列宽度
    if (customColumn.length > 0) {
      const divide = Math.floor(lastWidth / customColumn.length)
      customColumn.forEach((index, i) => {
        if (i === customColumn.length - 1) {
          colWidths[index] = Math.max(lastWidth, 30)
        } else {
          colWidths[index] = divide
          lastWidth = Math.max(lastWidth - divide, 30)
        }
      })
    }
  }

  tableStore.colWidths = colWidths
  const maxWidth = colWidths.reduce((acc, cur) => acc + cur, 0)
  tableStore.contentWidth = Math.max(maxWidth, tableStore.width)
}

// 更新表格数据的方法
const updateTableData = (data: any[]) => {
  // 确保是数组并创建新引用以触发响应式更新
  tableStore.data = Array.isArray(data) ? [...data] : []
}

// 更新表格高度的方法
const updateTableBodyHeight = (height: number) => {
  tableStore.bodyHeight = height
}

// 防抖更新函数
const update = _.debounce(() => {
  if (!rootElement.value) return

  try {
    const { clientWidth, clientHeight } = rootElement.value
    updateTableWidth(clientWidth)

    if (head.value && props.showPagination) {
      const headHeight = head.value.clientHeight
      const paginationHeight = 0
      // pagination.value?.clientHeight ||
      const bodyHeight = clientHeight - headHeight - paginationHeight
      updateTableBodyHeight(Math.max(0, bodyHeight))
    } else if (head.value) {
      const headHeight = head.value.clientHeight
      updateTableBodyHeight(clientHeight - headHeight)
    }

    // 更新滚动条
    if (scrollbar.value && typeof scrollbar.value.update === 'function') {
      scrollbar.value.update()
    }
  } catch (error) {
    console.error('Table update error:', error)
  }
}, 30)

// 监听数据变化
watch(
  () => props.data,
  (newData) => {
    updateTableData(newData)
    
  },
  { deep: true }
)

// 监听列变化
watch(
  () => props.columns,
  (newColumns) => {
    tableStore.columns = Array.isArray(newColumns) ? [...newColumns] : []
  },
  { deep: true }
)

// 处理滚动事件
const handleScroll = (event: any) => {
  if (head.value) {
    head.value.scrollLeft = event.scrollLeft
  }
}

// 处理分页变化
const handleCurrentChange = (currentPage: number) => {
  emit('current-change', currentPage)
}

// 生命周期
onMounted(() => {
  // 初始化数据
  tableStore.columns = Array.isArray(props.columns) ? [...props.columns] : []
  tableStore.data = Array.isArray(props.data) ? [...props.data] : []

  // 初始更新

  // 添加 resize 监听器
  if (rootElement.value) {
    // addResizeListener(rootElement.value, update)
  }
})

onUnmounted(() => {
  // 移除 resize 监听器
  if (rootElement.value) {
    // removeResizeListener(rootElement.value, update)
  }
})
</script>

<style lang="scss">
@use './style.scss';
</style>
